const axios = require('axios');
const { buildPrompt, extractMongoPipeline, getHumanAnswer } = require('../utils/buildPrompt');
const { Status, Type, Department, JobTicket } = require('../utils/dbs');
const ISDEBUG = process.env.ISDEBUG
const LANGMODEL = 'qwen3:8b'
const { countTime } = require('../utils/countTime');
const dbType = require('../utils/mongoTypeNew');

//自检函数
const checkSelf = async (code, question, dbType) => {
    return new Promise(async (resolve, reject) => {
        let step3s = Date.now()
        const response = await axios.post(
            process.env.AIURL,
            {
                model: LANGMODEL,
                prompt: `
【角色】
你是一个 MongoDB 代码审核专家，请对以下你先前生成的内容${code}进行审核，
【任务】
如果满足${question}和数据库的结构,输出其原有JSON数组,不满足输出严格合法的 JSON 数组,不要解释。
【数据库结构】
${JSON.stringify(dbType, null, 2)}
`,
                stream: false,
                "options": {
                    "temperature": 0,
                    "top_k": 1,
                }
            },
        );
        if (response) {
            let coderes = JSON.parse(JSON.stringify(code))
            coderes.pipeline = response
            resolve(coderes)
            let step4e = Date.now()
            console.log('STEP3大模型调用耗时', countTime(step3s, step4e))
            console.log(response.data.response, 'response')
        }
    })
}

// 调用大模型生成 MongoDB 聚合查询
exports.queryByAI = async (ctx) => {
    const { question } = ctx.request.body;
    if (!question) {
        ctx.status = 400;
        ctx.body = { error: '缺少问题' };
        return;
    }
    try {
        // 1. 构建 Prompt
        const prompt = buildPrompt(question, dbType);
        // 2. 调用大模型 API
        let step1s = Date.now()
        const response = await axios.post(
            process.env.AIURL,
            {
                model: LANGMODEL,
                prompt: prompt,
                stream: false,
                "options": {
                    "temperature": 0,
                    "top_k": 1,
                }
            },
        );
        if (response) {
            let step1e = Date.now()
            console.log('STEP1大模型调用耗时', countTime(step1s, step1e))

            // 3. 提取聚合管道（从 AI 回答中提取 JSON）
            const aiResponse = response.data.response;
            console.log(aiResponse, 'aiResponse')
            let pipeline = extractMongoPipeline(aiResponse);
            if (!pipeline) {
                ctx.status = 400;
                ctx.body = { error: '数据结构解析失败' };
                return
            }
            let collection = pipeline[0].db;
            if (!collection) {
                ctx.status = 400;
                ctx.body = { error: '我不明白' };
                return
            }
            let fpipeline = pipeline[0].pipeline
            if (fpipeline.length == 0) {
                ctx.status = 400;
                ctx.body = { error: '我不明白' };
                return
            }
            // 4. 执行聚合查询
            let collectionModel;
            switch (collection) {
                case 'Status':
                    collectionModel = Status;
                    break;
                case 'Type':
                    collectionModel = Type;
                    break;
                case 'Department':
                    collectionModel = Department;
                    break;
                case 'JobTicket':
                    collectionModel = JobTicket;
                    break;
                case 'Product':
                    collectionModel = Product;
                    break;
                default:
                    ctx.status = 400;
                    ctx.body = { error: '不支持的集合类型' };
                    return
            }
            console.log(collectionModel, '集合命中')
            if (ISDEBUG) {
                console.log('查询语句')
                console.log(fpipeline)
                console.log('查询语句')
                console.log(JSON.stringify(fpipeline))
            }

            //自检
            // let checkResult = await checkSelf(JSON.stringify(fpipeline), question, dbType)
            // let fpipeline2 = extractMongoPipeline(checkResult);
            // if (!fpipeline2) {
            //     ctx.status = 400;
            //     ctx.body = { error: '数据结构解析失败' };
            //     return
            // }
            //取消自检
            // let fpipeline2 = fpipeline
            let step2s = Date.now()
            // 直接使用模型而不是 eval，更安全且性能更好
            const result = await collectionModel.aggregate(fpipeline, {
                allowDiskUse: true // 当数据量大时允许使用磁盘
            });
            if (result) {
                let step2e = Date.now()
                console.log('STEP2数据库查询耗时', countTime(step2s, step2e))
            }

            let step4s = Date.now()
            const fresult = await getHumanAnswer(question, result, dbType)
            if (fresult) {
                let step4e = Date.now()
                console.log('STEP4大模型回答耗时', countTime(step4s, step4e))
            }

            // 5. 返回结果
            ctx.body = {
                question,
                mongo: pipeline,
                udata: result,
                data: fresult
            };
        }
    } catch (error) {
        console.error('AI 查询失败:', error.message);
        console.error('AI 查询语句:', fpipeline2);
        ctx.status = 500;
        ctx.body = { error: 'AI查询失败', detail: error.message, fpipeline: fpipeline2 };
    }

};

exports.fqueryByAI = async (ctx) => {
    return new Promise(async (resolve, reject) => {
        const { question } = ctx.request.body;
        if (!question) {
            reject('缺少问题')
        }
        try {
            // 1. 构造 Prompt
            const prompt = buildPrompt(question, dbType);
            // 2. 调用 DeepSeek API
            const response = await axios.post(
                process.env.AIURL,
                {
                    model: LANGMODEL,
                    prompt: prompt,
                    stream: false,
                    "options": {
                        "temperature": 0,
                        "top_k": 1,
                    }
                }
            );
            if (response) {
                // 3. 提取聚合管道（从 AI 回答中提取 JSON）
                const aiResponse = response.data.response;
                console.log('回答生成')
                let pipeline = extractMongoPipeline(aiResponse);
                console.log(pipeline)
                if (!pipeline) {
                    reject('数据结构解析失败')
                }

                let collection = pipeline[0].db;
                if (!collection) {
                    reject('我不明白')
                }
                let fpipeline = pipeline[0].pipeline
                if (fpipeline.length == 0) {
                    reject('我不明白')
                }
                // 4. 执行聚合查询
                let collectionModel;
                switch (collection) {
                    case 'Status':
                        collectionModel = Status;
                        break;
                    case 'Type':
                        collectionModel = Type;
                        break;
                    case 'Department':
                        collectionModel = Department;
                        break;
                    case 'JobTicket':
                        collectionModel = JobTicket;
                        break;
                    case 'Product':
                        collectionModel = Product;
                        break;
                    default:
                        reject('不支持的集合类型');
                        return;
                }
                console.log(collectionModel, '集合命中')
                if (ISDEBUG) {
                    console.log('查询语句')
                    console.log(fpipeline)
                    console.log('查询语句')
                    console.log(JSON.stringify(fpipeline))
                }
                // 直接使用模型而不是 eval，更安全且性能更好
                const result = await collectionModel.aggregate(fpipeline, {
                    allowDiskUse: true // 当数据量大时允许使用磁盘
                });
                const fresult = await getHumanAnswer(question, result, dbType)
                resolve(fresult)
            }


        } catch (error) {
            reject(error?.message || error)
        }
    })
};








